﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.SharpZipLib.Zip;

namespace Minecraft.ContentInstaller
{
    public class MinecraftContentManager
    {
        private string _JarPath;
        private ZipFile MinecraftBinary;

        #region Constructors

        public MinecraftContentManager()
        {
            _JarPath = MinecraftPaths.Jar;

            if (!File.Exists(_JarPath))
                throw new FileNotFoundException("Minecraft is not installed in the expected location.", _JarPath);

            LoadMinecraft();
        }

        public MinecraftContentManager(string jarPath)
        {
            if (!File.Exists(jarPath))
                throw new FileNotFoundException("", jarPath);

            _JarPath = jarPath;

            LoadMinecraft();
        }

        #endregion

        private void LoadMinecraft()
        {
            MinecraftBinary = new ZipFile(_JarPath);
        }

        /// <summary>
        /// Replaces a single file within Minecraft.
        /// </summary>
        /// <param name="contentInfo">A file to add.</param>
        public void AddFile(MinecraftContentInfo contentInfo)
        {
            if (!File.Exists(contentInfo.Source))
                throw new FileNotFoundException(
                    "The source file was not found.",
                    contentInfo.Source);
            
            MinecraftBinary.BeginUpdate();

            IStaticDataSource Data = new StaticDiskDataSource(contentInfo.Source);
            MinecraftBinary.Add(Data, contentInfo.Destination, CompressionMethod.Stored);

            MinecraftBinary.CommitUpdate();
        }

        /// <summary>
        /// Creates a directory within Minecraft.
        /// </summary>
        /// <param name="DirectoryPath">The directory path to create.</param>
        public void AddDirectory(string DirectoryPath)
        {
            try
            {
                MinecraftBinary.BeginUpdate();
                MinecraftBinary.AddDirectory(DirectoryPath);
                MinecraftBinary.CommitUpdate();
            }
            catch { }
        }

        /// <summary>
        /// Replaces a set of files within Minecraft.
        /// </summary>
        /// <param name="contentInfo">A set of files to add.</param>
        public void AddFiles(MinecraftContentInfo[] contentInfo)
        {
            MinecraftBinary.BeginUpdate();

            foreach (MinecraftContentInfo Content in contentInfo)
            {
                IStaticDataSource Data = new StaticDiskDataSource(Content.Source);
                MinecraftBinary.Add(Data, Content.Destination, CompressionMethod.Stored);
            }

            MinecraftBinary.CommitUpdate();
        }

        /// <summary>
        /// Determines if a given file is present within Minecraft.
        /// </summary>
        /// <param name="File">The path within Minecraft to examine.</param>
        public bool ContainsFile(string File)
        {
            return (MinecraftBinary.GetEntry(File) != null);
        }

        public void Open()
        {
            LoadMinecraft();
        }
        public void Close()
        {
            MinecraftBinary.Close();
        }

    }

    /// <summary>
    /// Represents a file to be added to, or replaced within, Minecraft.
    /// </summary>
    public struct MinecraftContentInfo
    {
        /// <summary>
        /// The path on disk to the item.
        /// </summary>
        public string Source;
        /// <summary>
        /// The location within minecraft.jar to save it to.
        /// </summary>
        public string Destination;

        //TODO: Support for partial image items
    }
}
